/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import * as WareHouseApi from '@src/api/WareHouseApi.ts';
import { getRichTextContent } from '@src/api/SystemApi';

/* mixin */
import ReceiptMixin from '../TaskReceiptMixin';
import QualityMixin from './quality-mixin';
import RuleReceiptMixin from './rule-receipt-mixin';

/* util */
import * as FormUtil from '@src/component/form/util';
import * as util from '@src/modules/task/util/receipt';
import _, { forEach } from 'lodash';
import { getRootWindow, scrollIntoFirstRequireDom } from '@src/util/dom';
import i18n from '@src/locales'
import { useFormTimezone, useStateSystemFormBuilderCell } from 'pub-bbx-utils'
const { disposeFormViewTime, disposeFormSubmitTime } = useFormTimezone()

/* enum */
import { TaskEventNameMappingEnum } from '@model/enum/EventNameMappingEnum.ts';
import TableNameEnum from '@model/enum/TableNameEnum.ts';

/* components */
import MaterialReturnInformationDialog from '@src/component/form/components/FormMaterialReturn/components/MaterialReturnInformationDialog';
import MaterialReconfirmDialog from '../../MaterialReconfirmDialog';
import FaultTable from '@src/modules/task/editAllot/components/PartSeviceList/components/FaultTable.vue';
import FormCellChange from '@src/component/compomentV2/FormCellChange'
// 国际化灰度
import useFormMultiLanguage from '@hooks/useFormMultiLanguage'
const { internationalGray } = useFormMultiLanguage()
import { currencyOption } from '@src/util/currency'
import { getCurrencyTypeName } from '@src/util/currency'
export default {
  name: 'task-receipt-edit-view',
  mixins: [ReceiptMixin, QualityMixin, RuleReceiptMixin],
  props: {
    partField: {
      type: Array,
      default: () => [],
    },
    receiptFields: {
      type: Array,
      default: () => [],
    },
    taskFields: {
      type: Array,
      default: () => [],
    },
    sparePartCardList: {
      type: Array,
      default: () => [],
    },
    intelligentConfig: {
      type: Object,
      default: () => ({}),
    }
  },
  provide() {
    return {
      // 编辑回执 或者 回执暂存保存
      isEdit: this.action === 'edit' || this.hasReceiptDraft
    }
  },
  data() {
    return {
      pending: false,
      visible: false,
      init: false,
      action: '',
      isEdit: false,
      mode: TableNameEnum.TaskReceipt,
      serviceList: [], // 服务项目清单列表
      serviceFields: [], // 服务清单字段
      sparepartList: [], // 备件清单列表
      serviceQualityStatus: '',// 产品的质保状态
      currencyType: 'CNY',
      internationalGray,
      fieldArr: [],
      formCellCount: 1,
      needServerDeleFiles:[]
    };
  },
  computed: {
    currencyOptionSelect() {
      return currencyOption.map(item=> {
        return {
          value: item.value,
          text: item.label
        }
      })
    },
    /**
     * @description 弹窗标题
     */
    title() {
      return this.action == 'edit' ? i18n.t('task.detail.components.editReceipt') : i18n.t('common.task.button.finish');
    },
    /**
     * @description 回执自定义字段
     */
    fields() {
      return this.notCustom ? this.notCustomFields : this.receiptFields;
    },
    /**
     * @description 回执详情数据
     */
    receiptData() {
      return this.initData?.receiptTaskForUpdate || {};
    },
    /**
     * @description 备件、服务项目、折扣费用数据集合
     * 新增 物料核销、物料返还
     */
    expenseSheet() {
      let data = this.initData.receiptExpenseSheetForUpdate || {};
      if (this.isFreeServiceFee && data.serviceExpense) {
        data.serviceExpense = data.serviceExpense.map(item => {
          return {
            ...item,
            salePrice: 0,
            subtotal: 0,
          };
        });
      }
      let colums = [
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel1'),
          field: 'name'
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.colum1'),
          field: 'sn'
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel4'),
          field: 'property'
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel11'),
          field: 'unit'
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel5'),
          field: 'snManage'
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel6'),
          field: 'salePrice',
        }, 
        {
          label: i18n.t('common.form.preview.materialReturn.tableLabel7'),
          field: 'warrantyStatus'
        },
        {
          label: i18n.t('common.form.preview.sparepart.colum9'),
          field: 'warehouseName',
        }, 
        {
          label: i18n.t('common.form.preview.sparepart.colum12'),
          field: 'positionName',
        },
        {
          label: i18n.t('common.form.preview.sparepart.colum20'),
          field: 'number',
        },
        {
          label: i18n.t('common.form.preview.sparepart.colum22'),
          field: 'replacedMaterial',
          width:120
        },
        {
          label: i18n.t('common.form.preview.sparepart.colum24'),
          field: 'snList',
          width:120
        },
        {
          label: i18n.t('common.form.preview.sparepart.colum23'),
          field: 'replacedSnList',
          width:120
        }
      ]
      // fix: 修改备件数量可选数量，应当计算当前数量和仓库数量
      if (data.sparePartsExpense) {
        data.sparePartsExpense = data.sparePartsExpense.map(item => {
          // 非直接出库的备件
          if (item.spType != 0 && this.action == 'edit')
            item.repertoryCount = item.repertoryCount + item.number;
          if (this.isFreeSparePartFee) {
            item.salePrice = 0;
            item.subtotal = 0;
          }
          return item;
        });
      }
      return data;
    },
    /**
     * @description 显示折扣费用
     */
    showDiscountCost() {
      let { showSparepart, showService, showDiscountCost } =
        this.taskType?.options || {};
      return (showSparepart || showService) && showDiscountCost;
    },
    /**
     * @description 支付方式
     */
    paymentMethod() {
      let { state, attribute = {} } = this.task;
      let stateArr = ['finished', 'costed', 'closed', 'offed'];
      let paymentMethod = this.receiptData?.attribute?.paymentMethod || '';

      return stateArr.indexOf(state) > -1
        ? attribute.paymentMethod
        : paymentMethod;
    },
    /**
     * @description 显示支付方式
     */
    showPaymentMethod() {
      let { state, onceRollback } = this.task;
      let stateArr = ['finished', 'costed', 'closed', 'offed'];

      return (
        (onceRollback < 1 || stateArr.indexOf(state) > -1) && this.paymentMethod
      );
    },
    /**
     * @description 是否开启支付
     */
    openPay() {
      let { version, onlineAlipay } = this.initData?.paymentConfig || {};

      return version == 1 && onlineAlipay;
    },
    /**
     * @description 备件清单附加组件
     */
    sparepartCard() {
      return (
        this.initData.cardInfo.find(card => card.specialfrom == '备件清单') ||
        {}
      );
    },
    /**
     * @description 是否开启云仓灰度
     */
    isCloudwarehouse() {
      const RootWindow = getRootWindow(window);
      return RootWindow.grayAuth?.taskCloudWarehouse || false;
    },
    /**
     * @description 是否配置物料申领附加组件
     */
    isMaterialCard() {
      return (
        this.initData.cardInfo?.length > 0 &&
        this.initData.cardInfo.some(card => card.specialfrom == '物料申领')
      );
    },
    //  是否需要填写被替换物料
    showReplacedMaterialCheck() {
      let { replacedMaterialCheck } = this.initData?.materialInfo || {}
      return replacedMaterialCheck || false
    },
    // 物料返还field
    isMaterialReturnFieldSetting() {
      const filed = this.fields.find(field => field.fieldName == 'materialReturn') || {}
      return filed.setting || {}
    },
    // 物料返还后是否将工单对应的产品禁用 
    isMaterialReturnProductDisable() {
      let { productDisable } = this.isMaterialReturnFieldSetting
      return productDisable || false
    },
    // 物料返还 关联字段
    isMaterialReturnShowFields() {
      let { showFields } = this.isMaterialReturnFieldSetting
      return showFields || []
    },
    // 物料核销field
    isMaterialVerifyEliminateFieldSetting() {
      const filed = this.fields.find(field => field.fieldName == 'materialVerifyEliminate') || {}
      return filed.setting || {}
    },
    // 物料核销后是否在客户名下生成新产品  
    isMaterialVerifyEliminateCreateNewProduct() {
      let { createNewProduct } = this.isMaterialVerifyEliminateFieldSetting
      return createNewProduct || false
    },
    // 物料核销 关联字段
    isMaterialVerifyEliminateReconfirmShowFields() {
      let { showFields } = this.isMaterialVerifyEliminateFieldSetting
      return showFields || []
    },
    // 物料核销 是否开启配件结算方式 
    isShowSettleType() {
      // 是否开启慈星物料核销灰度
      const RootWindow = getRootWindow(window)
      const isCiXingMaterialGray = RootWindow.grayAuth?.CIXING_MATERIAL_SETTLE

      // 是否开启配件结算方式
      const { isShowSettleType = false } = this.isMaterialVerifyEliminateFieldSetting
      
      return isCiXingMaterialGray && isShowSettleType
    },
    //  质保期为保外的物流必须返还
    showUnexpiredMaterialReturnCheck() {
      let { unexpiredMaterialReturnCheck } = this.initData?.materialInfo || {}
      return unexpiredMaterialReturnCheck || false
    },
    //  质保期为保内的物流必须返还
    showExpiredMaterialReturnCheck() {
      let { expiredMaterialReturnCheck } = this.initData?.materialInfo || {}
      return expiredMaterialReturnCheck || false
    },
    // 工时记录控件的配置
    hoursRecordCardConfig(){
      const cardInfo = this.initData?.cardInfo || []
      const cardConfig = cardInfo.filter(card => card.specialfrom == '工时记录')[0] || {}
      // cardConfig.config 是一个JSON字符串
      return cardConfig.config ? JSON.parse(cardConfig.config) : {}
    },
    // 华大基因私有灰度
    isBgiPrivate() {
      const RootWindow = getRootWindow(window);
      return Boolean(RootWindow.grayAuth?.bgiPrivate) || false;
    },
    hasReceiptDraft() {
      return Boolean(this.initData?.hasReceiptDraft)
    },
    showTotalFee() {
      return (this.showSparepart || this.showService || (this.isCloudwarehouse && this.showMaterialVerifyEliminate)) && this.serviceProviderShowPrice
    },
    currencyTypeName() {
      let currencyType = this.currencyType || 'CNY'
      return getCurrencyTypeName(currencyType)
    },
    // 判断是否需要验证物料申领 + 返还个人库 + 返还至仓库的数量
    returnUnusedCheck(){
      let { setting } = this.fields?.find(item=>item.fieldName == 'materialReturn') || {}
      return !!setting?.returnUnusedCheck
    },
    /**工单关联产品ids */
    productIds() {
      return this.initData?.task?.products?.map(item => item.id) || [];
    },
    // 是否开备件返还灰度
    isSparePartsReturnExpense() {
      const RootWindow = getRootWindow(window)
      return Boolean(RootWindow.grayAuth?.TASK_SPARE_PART_RETURN)
    },
  },
  methods: {
    /**
     * @description 更新表单数据
     */
    update({ field, newValue, oldValue }) {
      let { fieldName, displayName } = field;

      if (this.$appConfig.debug) {
        console.info(
          `[FormBuilder] ${displayName}(${fieldName}) : ${JSON.stringify(
            newValue
          )}`
        );
      }
      this.$set(this.form, fieldName, newValue);
    },
    /**
     * @description 弹窗关闭重置数据
     */
    reset() {
      this.form = {};
      this.init = false;
    },
    /**
     * @description 打开弹窗
     */
    async openDialog(action) {

      let expenseSheet = _.cloneDeep(this.expenseSheet);

      // 初始化默认值
      let form = {
        task: disposeFormViewTime(this.fields, this.receiptData),
        expenseSheet,
      };

      if(internationalGray) {
        const field = this.fields.find(item => item.formType === 'currencyType')
        this.currencyType = expenseSheet?.settlementCurrency || field?.setting?.defalutCurrency ||'CNY'
      }
      // 因为完成回执和暂存时，取的工单id是通过 this.receiptData 后端详情接口取的，但是后端数据会存在工单id丢失且定位不到原因，所以前端做一下空值处理,bug编号15288
      // 排查bug16718，可能是receiptTaskForUpdate里面的工单id不对，导致前端传给后端的工单id数据就不对，这里做个兼容，看以后还会不会出现问题
      // 优先取initData里面的工单id
      form.task.id = this.task.id || this.receiptData.id

      // 预计里程 完成回执时后端未将数据添加至 receiptTaskForUpdate 里，直接从 task 工单数据中获取数据回填
      if(form.task.hasOwnProperty('estimatedMileage')){
        form.task.estimatedMileage = this.task?.estimatedMileage || this.receiptData?.estimatedMileage || 0
      }
      form.sparePartsReturnExpense = this.receiptData?.attribute?.sparePartsReturnExpense || [];

      form = util.packToForm(this.fields, form);
      form = this.changeForm(form)
      const formValue = FormUtil.initialize(this.fields, form);
      this.form = { ...formValue, taskData: this?.task || {} }

      // 产品质保状态
      if (this.initData.task?.products?.[0]?.qualityStatus) {
        this.serviceQualityStatus = (this.initData.task.products[0].qualityStatus === 'IN') ? this.$t('common.base.warranty') : this.$t('common.base.surrender')
        if (this.form?.serviceIterm?.length > 0) {
          this.form.serviceIterm.forEach((item) => {
            item.serviceQualityStatus = this.serviceQualityStatus
          })
        }
      }
      // TODO 国际化灰度添加
      if(this.internationalGray && this.form?.serviceIterm?.length > 0) {
        this.form.serviceIterm.forEach((item) => {
          let salePriceCurrency = item.realPriceCurrency || 'CNY'
          this.$set(item, 'salePriceCurrency', salePriceCurrency)
        })
      }
      let richtextObj_ = {};
      this.fields.forEach(async field => {
        if (field.formType == 'richtext') {
          // 富文本信息需要从接口获取
          let { fieldName } = field;
          let id = this.form[fieldName];
          if(id){
            richtextObj_[id] = fieldName;
          }
        }
      });
      let richtextIds = Object.keys(richtextObj_) || [];
      if (richtextIds.length) {
        let content_ = await getRichTextContent({
          ids: richtextIds,
        });
        let richtextCon = '';
        if (content_.code == 0) {
          content_.result?.forEach((item, index) => {
            let key_ = richtextIds[index];
            let fieldName_ = richtextObj_[key_];
            richtextCon = item.content;
            this.form[fieldName_] = richtextCon;
          });
        }
      }

      // 编辑回执时配件增加安装产品和安装位置 博立定制 后期可能通用
      if (this.partField.length) {
        this.partField.forEach((part, ind) => {
          this.form.sparepart.forEach(_sparepart => {
            if (part.fieldName == 'installProductId') {
              _sparepart.installProductId = _sparepart.attribute
                ? _sparepart.attribute.installProductId
                : '';
            } else if (part.fieldName == 'installPosition') {
              _sparepart.installPosition = _sparepart.attribute
                ? _sparepart.attribute.installPosition
                : '';
            }
          });
        });
      }
      // 自定义回执表单自定义字段length等于0时直接完成
      if (this.fields.length == 0) {
        let params = util.packToReceipt(this.fields, this.form);
        params = this.packFormat(params);
        params = this.globalFormSubmissionDataProcessingHandler(
          this.fields,
          params
        );
        this.finish(params);
        return;
      }
      
      // 该方法放到init = true上面
      await this.fetchRuleList()

      this.init = true;
      this.action = action;

      // 获取备件清单数据
      if (this.showSparepart) this.getInventoryRecordGroup();

      this.$nextTick(() => {
        this.updateConfigForSparepart();
      });

      this.visible = true;
    },

    // 改变form的值,很抱歉这里去处理值，我知道肯定有专门的地方去处理值的，但是时间紧，我没时间去理逻辑了。- -！
    changeForm(form){
      // 如果物料核销存在的话
      if(form?.materialVerifyEliminate?.length){
        form.materialVerifyEliminate.forEach(item => {
          item.SN = item?.snList?.length ? item.snList.join() : ''
          item.replacedMaterialSN = item?.replacedSnList?.length ? item.replacedSnList.join() : ''
          let replacedMaterial = item?.attribute?.replacedMaterial ?? null
          if(replacedMaterial){
            item.replacedMaterial = {
              ...replacedMaterial,
              materialName:replacedMaterial?.name || replacedMaterial?.materialName,
              id:replacedMaterial?.id || replacedMaterial?.materialId,
              value:replacedMaterial.id,
              label:replacedMaterial.name,
            }
          } 
          item.warehousePositionName = item.positionName || item.warehouseName
          item.positionName = item.positionName || item.warehouseName

        })
      }
      // 如果物料返还存在的话
      if(form?.materialReturn?.length){
        form.materialReturn.forEach(item => {
          item.initMaterialSN = item.attribute?.initMaterialSN
          item.materialId = item.sn
          item.SN = item?.snList?.length ? item.snList.join() : ''
        })
      }
        
      return form
    },

    /**
     * @description 更新折扣费用
     */
    updateDisExpense(event) {
      let value = event.target.value;
      const REG = /^[0-9]+([.]{1}[0-9]{0,2}){0,1}$/;
      this.form.disExpense = REG.test(value)
        ? parseFloat(value)
        : Math.floor((value * 100) / 100);
    },
    /**
     * @description 折扣费用校验
     */
    disExpenseBlur(event) {
      let value = event.target.value;
      let totalExpense =
        Number(this.sparepartTotal) +
        Number(this.serviceTotal) +
        Number(this.materialTotal);

      if (Math.abs(value) > totalExpense) {
        this.form.disExpense = 0;
        return this.$platform.notification({
          type: 'error',
          title: i18n.t('common.base.toast'),
          message: i18n.t('task.tip.receiptTip1'),
        });
      }
      this.form.disExpense = 0 - Math.abs(value);
    },
    // 配置了规则的折扣费用
    updateDisExpenseRule(row) {
      const REG = /^[0-9]+([.]{1}[0-9]{0,2}){0,1}$/;

      row.disExpense = REG.test(row.disExpense)
        ? parseFloat(row.disExpense)
        : Math.floor((row.disExpense * 100) / 100);

      let total = Number(row.materialTotal) + Number(row.serviceTotal)
      if (parseFloat(row.disExpense) > parseFloat(total)) {
        row.disExpense = 0;
        row.totalExpense = total.toFixed(2);
        return this.$platform.notification({
          type: 'error',
          title: i18n.t('common.base.toast'),
          message: i18n.t('task.tip.receiptTip1'),
        });
      }
  
      total = total - Number(row.disExpense)
  
      row.totalExpense = total.toFixed(2);
    },
    /**
     * @description 将回执数据格式化
     */
    packFormat(params) {
      if (!this.notCustom) params.task.attribute['customReceipt'] = true;

      let paymentMethod = this.isPaySuccess
        ? '在线支付-支付宝'
        : this.task.state == 'processing'
        ? ''
        : this.paymentMethod;
      params.task.attribute['paymentMethod'] = paymentMethod || '';

      params.task = disposeFormSubmitTime(this.fields, params.task)

      let task = Object.assign({}, params.task);

      delete params.task;

      return disposeFormSubmitTime(this.fields, Object.assign(params, task));
    },
    // 结算规则数据处理
    taskSettlementFunc() {
      let ruleTaskSettlement = (this.receiptRulesList || []).map(item => {
        return {
          ...item,
          ruleName: item?.settlementRules || '',
          sparePartTotal: this.totalData[0]?.sparepartTotal,
          disExpense: item?.settlementRules?.length > 0 ? item?.disExpense :this.totalData[0]?.disExpense.toFixed(2), // 数据兼容，如果新版本的结算有值取新的值，没有取旧值。
          // 当前行没有配置规则的话，就取之前老的计算规则
          totalExpense: item?.settlementRules?.length > 0 ? item?.totalExpense : this.totalExpenseSet(item) ,
        }
      });

      return ruleTaskSettlement;
    },

    // 如果只有一条数据的话，取之前的老数据，多余的话，就取最新的
    totalExpenseSet(item) {
      return (this.receiptRulesList.length === 1 ? (this.totalData[0]?.totalExpense) : item.totalExpense)
    },


    /**
     * @description 暂存
     */
    draft() {
      this.$track.clickStat(this.$track.formatParams('TEMPORARY_SAVE', '暂存', 'FINISH_TASK'));

      this.pending = true;
      // 结算规则
      let ruleTaskSettlement = this.taskSettlementFunc();

      // 处理国际化时间转换
      let formValue = disposeFormSubmitTime(this.fields, this.form)

      let params = util.packToReceipt(this.fields, formValue, ruleTaskSettlement);
      params = this.globalFormSubmissionDataProcessingHandler(
        this.fields,
        params
      );
      params.taskId = (params.task || {}).id;
      if (this.task?.inApprove == 1) {
        params.isApproveEditReceipt = true;
      }

      params.taskSettlement = ruleTaskSettlement;
      params.settlementCurrency = this.currencyType;
      params.baseTaskFaultLibrary = this.form?.newFaultLibrary || [];
      params.sparePartsReturnExpense = this.form?.sparePartsReturnExpense || [];

      if(this.needServerDeleFiles.length){
        params.deleteFiles = this.needServerDeleFiles
      }

      TaskApi.receiptDraft(params)
        .then(res => {
          if (res.success) {
            let msgToast = this.task?.inApprove == 1 ? i18n.t('common.base.saveSuccess') : i18n.t('common.base.temporarySaveSuccess');
            this.$platform.notification({
              type: 'success',
              title: msgToast,
            });

            this.refreshTab();
          } else {
            this.$platform.alert(res.message);
            this.pending = false;
          }
        })
        .catch(err => {
          this.pending = false;
        });
    },
    // 同步报价单
    synchronizeQuotedPrice() {
      if(!this.isBgiPrivate) return;
      this.pending = true;
      TaskApi.getTaskSyncQuote({taskId: this.task.id}).then(res => {
        if(!res.success) return this.$platform.alert(res.message);

        const { serviceExpense, materialExpense, discountExpense } = res.data;
        // 物料核销
        if(this.form.materialVerifyEliminate && materialExpense.length) {
          this.form.materialVerifyEliminate = materialExpense;
        }
        // 服务项目
        if(this.form.serviceIterm && serviceExpense.length) {
          serviceExpense.forEach(item => {
            item.oldPrice = item.salePrice || 0;
          })
          this.form.serviceIterm = serviceExpense;
        }
        // 折扣费用
        if (discountExpense.salePrice != null) {
          this.form.disExpense = discountExpense.salePrice || 0;
          internationalGray ? this.currencyType = discountExpense.salePriceCurrency || 'CNY' : null;
        }
      }).catch(err => {
        console.error(err);
      }).finally(() => {
        this.pending = false;
      })
    },
    async confirmMaterial() {
      try {
        // 物料返还
        let materialReturn = _.cloneDeep(this.form.materialReturn)
        // 物料核销
        let materialVerifyEliminate = _.cloneDeep(this.form.materialVerifyEliminate)

        // 获取可禁用的产品
        let forbiddenProductData = []
        let forbiddenProductNum = false

        // 获取新建产品关联的产品类型
        let createProductsData = []
        let productTypeNum = false

        if (materialReturn && materialReturn.length > 0) {
          // 统一字段名
          materialReturn = materialReturn.filter(item => item.machine)
          materialReturn.forEach(item => {
            item.materialId = item.primaryId || item.materialId || item.id
            item.name = item.materialName || item.name
            item.serialNumber = item.SN || ''
          })
          // 物料返还IDS
          const returnIds = materialReturn.map(item => item.materialId)
          // 工单关联产品IDS
          const productIds = (this.initData?.task?.products || []).map(item => item.id)
          // 可以禁用的产品IDS
          const forbiddenProduct = await TaskApi.getProductByMat({ materielIdList: returnIds, productIds })
          const forbiddenProductIds = forbiddenProduct?.result || []

          // 可以禁用的产品 machine -> true属性为整机
          forbiddenProductData = (this.initData?.task?.products || []).filter(item => forbiddenProductIds.includes(item.id))
          // 工单关联产品与要返还的物料产品类型相同
          forbiddenProductNum = forbiddenProductData.length > 0
        }
        
        if(materialVerifyEliminate && materialVerifyEliminate.length > 0) {
          // 统一字段名
          materialVerifyEliminate.forEach(item => {
            item.materialId = item.primaryId || item.materialId || item.id
            item.name = item.materialName || item.name
            item.serialNumber = item.SN || ''
          })
          // 物料核销IDS
          const materialVerifyIds = materialVerifyEliminate.map(item => item.materialId)
          // 关联的产品类型
          const { result } = await TaskApi.getCatalogByMat({ materielIdList: materialVerifyIds })
          // 产品类型数量 > 0
          const productTypes = result || []
          // 新建产品数据
          const createProductsList = materialVerifyEliminate || []

          productTypeNum = productTypes.length > 0

          createProductsData = createProductsList.map(item => {
            const res = productTypes.filter(type => type.materialId == item.materialId)[0]
            const catalogs = res ? res.catalogs : []
            return {
              ...item,
              catalogs
            }
          }).filter(item => item?.catalogs?.length > 0 && item.machine)
        }

        // 可禁用产品数量 > 0 || 物料关联的产品类型 > 0
        if((forbiddenProductNum && forbiddenProductData.length) || (productTypeNum && createProductsData.length)) {
          this.$refs.materialReconfirmDialog.open(forbiddenProductData, createProductsData)
        } else {
          this.getMaterialInfo()
        }
      } catch (error) {
        console.error(error);
      }
    },
    submitMaterialReconfirm({ banProductIds, createProByMat }) {
      this.$set(this.form, 'banProductIds', banProductIds)
      this.$set(this.form, 'createProByMat', createProByMat)
      return this.getMaterialInfo()
      
    },
    // 填写返还物流信息 校验核销出库情况
    getMaterialInfo() {
      if (this.isMaterialReturn) {
        return this.$refs.materialReturnInformation.open();
      }
      if (this.isMaterialVerifyEliminate) {
        return this.verificationMaterialOutWarehouseComplete();
      }
    },

    // 工单关闭前检测未结束工时记录人员名单
    async finishTaskCheck(){
      this.$track.clickStat(this.$track.formatParams('FINISH', '完成回执', 'FINISH_TASK'));

      // isAutoEndTiming 是根据PC端工时记录的附加组件的是否结束计时来决定的。true是开启，false是关闭
      if(!this.hoursRecordCardConfig.isAutoEndTiming) return this.submitPre()
      const res = await TaskApi.checkWorkTimeBeforeFinishApi({ taskId : this.task?.id || '' })
      let hourRecordUserList = []
      if(res.success){
        hourRecordUserList = res.result
      }
      if(hourRecordUserList.length > 0 ){
        let nameList = hourRecordUserList.filter(user => Boolean(user?.name)).map(user => user.name) 
        let message = ''
        if(nameList.length > 3){
          nameList = nameList.slice(0, 3)
          message = i18n.t('task.tip.receiptTip2', {data1: nameList.join(), data2: hourRecordUserList.length})
        }else{
          message = i18n.t('task.tip.receiptTip3', {data: nameList.join()})
        }
        let confirm = await this.$platform.confirm(message);
        if(!confirm) return
        this.submitPre()
      }else{
        this.submitPre()
      }
    },
    async submitPre() {
      // 物料核销
      if(this.form?.materialVerifyEliminate?.length > 0){
        // 处理数据
        this.form.materialVerifyEliminate.forEach(item =>{
          let replacedMaterial = item.replacedMaterial ?? null
          if(replacedMaterial){
            const obj = {
              image:replacedMaterial.image,
              images:replacedMaterial.images,
              isReplaced:replacedMaterial.isReplaced,
              materialId:replacedMaterial.materialId || replacedMaterial.id,
              id:replacedMaterial.materialId || replacedMaterial.id,
              materialName :replacedMaterial.materialName || replacedMaterial.name,
              name :replacedMaterial.materialName || replacedMaterial.name,
              num: 1,
              materialSn :replacedMaterial.materialSn || replacedMaterial.sn,
              property :replacedMaterial.property || replacedMaterial.materialProperty,
              salePrice :replacedMaterial.salePrice || 0,
              unit :replacedMaterial.unit || replacedMaterial.materialUnit,
              snManage :replacedMaterial.snManage || replacedMaterial.name,
              warrantyStatus :replacedMaterial.warrantyStatus || '',
            }
            item.replacedMaterial = obj
          }

          console.log( item.replacedMaterial, ' item.replacedMaterialwarrantyStatus')
        })
        // TODO 国际化待办
        const materialSome = this.form?.materialVerifyEliminate.some(item=> item.snManage === '是' && !item.SN)
        if(materialSome) return this.$platform.alert(i18n.t('task.tip.receiptTip4'));
      }
      // 物料返还
      const field = this.fields.filter(item => item.formType === 'materialReturn')

      // 0 是必填，1 是非必填
      // if(!field.inNull){
      //   // 返还的物料必须存在质保期为保内的
      //   if(this.showExpiredMaterialReturnCheck){
      //     // 如果核销存在保内的物料，但是返还的物料中却没有则提示。
      //     // TODO 国际化待办
      //     const materialVerificationState = this.form?.materialVerifyEliminate?.length && this.form.materialVerifyEliminate.some(item => item.warrantyStatus === '保内')
      //     const materialReturnState = this.form?.materialReturn?.length && this.form.materialReturn.some(item => item.warrantyStatus === '保内')
      //     if(materialVerificationState && !materialReturnState) return this.$platform.alert(i18n.t('task.tip.receiptTip5'));
      //   }
      //   // 返还的物料必须存在质保期为保外的
      //   if(this.showUnexpiredMaterialReturnCheck){
      //     // 如果核销存在保外的物料，但是返还的物料中却没有则提示。
      //     // TODO 国际化待办
      //     const materialVerificationState = this.form?.materialVerifyEliminate?.length && this.form.materialVerifyEliminate.some(item => item.warrantyStatus === '保外')
      //     const materialReturnState = this.form?.materialReturn?.length && this.form.materialReturn.some(item => item.warrantyStatus === '保外')
      //     if(materialVerificationState && !materialReturnState) return this.$platform.alert(i18n.t('task.tip.receiptTip6'));
      //   }
      // }
      // 如果存在物料核销且存在被替换物料，则处理物料核销数据，进行数据合并 
      if(this.form?.materialVerifyEliminate?.length > 0 && this.showReplacedMaterialCheck){
        const replacedMaterialSome = this.form?.materialVerifyEliminate.some(item => {
          if(item.replacedMaterial){
            // TODO 国际化待办
            return item.replacedMaterial.snManage === '是' && !item.replacedMaterialSN
          }
        })
        if(replacedMaterialSome) return this.$platform.alert(i18n.t('task.tip.receiptTip7'));
        // 存在被替换物且当前物料是非SN的，最终需要合并相同的数据
        let copyMaterialData = []
        this.form.materialVerifyEliminate.forEach(item => {
          // TODO 国际化待办
          if(item.snManage === '否'){
            // 不是SN的则相同物料id，相同仓库和相同仓位算是同一种物料，且被替换物料也是一样的就合并
            let idx = copyMaterialData.findIndex(val => {
              let itemId = item.primaryId || item.materialId
              let valId = val.primaryId || val.materialId
              return Number(itemId) === Number(valId) && Number(item.warehouseId) === Number(val.warehouseId) && Number(item.positionId) === Number(val.positionId) && Number(item.replacedMaterial.id) === Number(val.replacedMaterial.id)
            })
            if(idx > -1) {
              const newItem = {
                ...copyMaterialData[idx],
                // ...item,
                number: item.number + copyMaterialData[idx].number,
              }
              copyMaterialData[idx] = newItem
            }else{
              copyMaterialData.push(item)
            }
          }else{
            copyMaterialData.push(item)
          }
        })
        this.form.materialVerifyEliminate = copyMaterialData
      }
      // 如果存在物料返还且存在被替换物料，则处理物料返还数据，进行数据合并
      if(this.form?.materialReturn?.length > 0 && this.showReplacedMaterialCheck){
        let copyMaterialData = []
        this.form.materialReturn.forEach(item => {
          // TODO 国际化待办
          if(item.snManage === '否'){
            // 不是SN的则相同物料id，相同仓库和相同仓位算是同一种物料
            let idx = copyMaterialData.findIndex(val => {
              let itemId = item.primaryId || item.materialId
              let valId = val.primaryId || val.materialId
              return Number(itemId) === Number(valId) && Number(item.warehouseId) === Number(val.warehouseId) && Number(item.positionId) === Number(val.positionId)
            })
            if(idx > -1) {
              const newItem = {
                ...copyMaterialData[idx],
                number: item.number + copyMaterialData[idx].number,
              }
              copyMaterialData[idx] = newItem
            }else{
              copyMaterialData.push(item)
            }
          }else{
            copyMaterialData.push(item)
          }
        })
        this.form.materialReturn = copyMaterialData
      }

      // 备件返还校验
      const sparePartsReturnExpenseField = this.fields.filter(item => item.formType === 'sparePartsReturnExpense');
      const partsReturnExpenseInfo = sparePartsReturnExpenseField?.[0] || {};
      if(partsReturnExpenseInfo.isNull == 0) {
        const showAlert = (messages) => {
          const message = messages.map(m => i18n.t(m)).join('\n');
          return this.$platform.alert(message);
        };

        // 检查备件函数
        /*
        * parts: 需要去比较的总数据（已核销备件的旧件必须返还：备件核销的数据 or 已申领未核销的备件必须返还：备件清单数据）
        * partsReturnExpense：已经添加的数据：需要校验添加的数量是否满足（已核销备件的旧件必须返还：备件返还的数据 or 已申领未核销的备件必须返还：备件返还的数据）
        * */
        const checkSpareParts = (parts, partsReturnExpense, mustReturn, useNumProperty = 'number') => {
          const partsReturnExpenseList = _.cloneDeep(partsReturnExpense);
          if (mustReturn && parts.length) {

            let msg1 = []
            // partsReturnExpense不存在parts的物料
            const serialNumberIds = partsReturnExpense?.map(x => x.serialNumber) ?? [];
            const list = parts.filter(item => !serialNumberIds.includes(item.serialNumber)) ?? []
            if (list?.length) {
              msg1 = list.map(x => i18n.t('task.detail.partReturnReceiptTip1', { name: x.name, useNum: x[useNumProperty], number: 0 }));
            }

            // 1. 先循环出所有相同的备件返还的serialNumber相同的备件。并相加返换的数量。
            const listMap = partsReturnExpenseList.reduce((acc, cur) => {
              const { serialNumber } = cur;
              if(!acc[serialNumber]){
                acc[serialNumber] = cur;
              }else {
                acc[serialNumber].number += cur.number;
              }
              
              return acc;
            }, {});

            // 备件返还数量 - (备件用量 | 备件清单已出库数量)
            const msg2 = parts.flatMap(x => {
              // 2. 再进行加减操作
              return Object.values(listMap).map(v => {
                if (v.serialNumber === x.serialNumber && v.number - x[useNumProperty] < 0) {
                  return i18n.t('task.detail.partReturnReceiptTip2', { name: v.name, useNum: x[useNumProperty], number: v.number });
                }
                return null;
              }).filter(Boolean);
            });

            const messages = [...msg1, ...msg2]

            if (messages.length) return messages;
          }
        };

        const { usedSparePartMustReturn, applySparePartMustReturn } = partsReturnExpenseInfo.setting || {};
        const { sparepart = [], sparePartsReturnExpense = [] } = this.form || {};
      
        // 已核销备件的旧件必须返还
        const usedCheck = checkSpareParts(sparepart, sparePartsReturnExpense, usedSparePartMustReturn);
        if (usedCheck) return showAlert(usedCheck);
      
        // 已申领未核销的备件必须返还
        const applyCheck = checkSpareParts(this.sparePartCardList, sparePartsReturnExpense, applySparePartMustReturn, 'useNum');
        if (applyCheck) return showAlert(applyCheck);

        // 已申领未核销的备件必须返还 添加"已申领未核销"的数量参数
        this.form.sparePartsReturnExpense.forEach(p => {
          const sparepartItem = sparepart.find(x => p.serialNumber === x.serialNumber) || {};
          const applyNumber = p.number - (sparepartItem.number || 0);

          if(applyNumber >= 0) p.applySparePartMustReturnNum = applyNumber;
        })
      }

      // 仅备件清单中的物料可返还-校验选择的备件是否有不是备件清单的
      if(partsReturnExpenseInfo?.setting?.onlySpartListReturn){
        // sparePartCardList：备件清单中已出库的备件 sparePartsReturnExpense：备件返回的备件
        let spareName = [];
        this.form.sparePartsReturnExpense?.forEach(item => {
          if(this.sparePartCardList?.length && this.sparePartCardList?.every(zitem => zitem.serialNumber !== item.serialNumber)) {
            spareName.push(item.name)
          }
        })

        if(spareName?.length) return this.$platform.alert(this.$t('common.task.spareReturnMustList', {spares: spareName?.join('、')}));

        // 判断从备件返回的备件的返还数量是否超过了备件清单的出库数量
        let names = [];
        this.sparePartCardList?.forEach(item => {
          let num = 0
          const parts = this.form.sparePartsReturnExpense?.filter(zitem => zitem.serialNumber === item.serialNumber)
          parts?.forEach(mitem => num+=mitem.number)
          if(item.useNum < num) {
            names.push(item.name)
          }
        })
        if(names?.length) return this.$platform.alert(this.$t('common.task.spareReturnNumList', {spares: names?.join('、')}));
      }

      if(this.returnUnusedCheck){
        let validateReturnUnusedCheckRes = await this.validateReturnUnusedCheck() 
        if(!validateReturnUnusedCheckRes) return
      }
      

      return this.submit();
    },
    /**
     * @description 检查物料出库是否完成
     */
    async verificationMaterialOutWarehouseComplete() {
      try {
        // 检查物料出库是否完成
        let result = await WareHouseApi.getOutWarehouseFlowFinished({
          sourceId: this.initData.task.id,
        });
        if (!result.data) {
          this.$platform.alert(
            i18n.t('task.tip.receiptTip8')
          );
        }

        this.completionReceipt()

      } catch (error) {
        console.log(error);
      }
    },
    /**
     * @description 完成、编辑回执
     */
    submit() {
      this.$refs.form.validate(false).then(async valid => {
        scrollIntoFirstRequireDom(this.$refs.form)
        if (!valid) return Promise.reject('validate fail.')

        if (this.task?.inApprove == 1) {

          //如果有物料返还
          if(this.isMaterialReturn) {
            return this.$refs.materialReturnInformation.open();
          }
          
          this.draft();
        } else {
          if(internationalGray) {
            let flag = true 
            let { materialVerifyEliminate=[], serviceIterm=[] } = this.form
            if(materialVerifyEliminate.length > 0 || serviceIterm.length > 0) {
              this.fieldArr = materialVerifyEliminate.concat(serviceIterm)
              flag = this.fieldArr.every(item => {
                if (item.salePriceCurrency == this.currencyType) return true
                return item.exchangeRate
              })
            }
            if(!flag) return this.$platform.alert(this.$t('common.currency.exchangeRateValidate'))
          }

          // 物料核销 开启配件结算方式 编辑回执二次确认
          if (this.isMaterialVerifyEliminate && this.isShowSettleType && this.action === 'edit') {
            const confirm = await this.$platform.confirm(this.$t('task.tip.receiptTip12'))
            if (!confirm) return
          }
          
          // 物料核销返还二次确认逻辑(核销返还有数据 && 开启了开关)
          if((this.isMaterialReturn || this.isMaterialVerifyEliminate) && (this.isMaterialReturnProductDisable || this.isMaterialVerifyEliminateCreateNewProduct) && this.task.state !== 'finished') {
            return this.confirmMaterial()
          } else if(this.isMaterialReturn || this.isMaterialVerifyEliminate) {
            return this.getMaterialInfo()
          }
          // 将物料校验放到表单校验后面 如果有物料核销或返还 会在物料弹窗确认后调用该方法
          this.completionReceipt()
        }
      })
      .catch(err => {
        this.pending = false;
      });
    },
    // 完成回执 
    async completionReceipt() {
      try {
        // 结算规则
        let ruleTaskSettlement = this.taskSettlementFunc();

        let params = util.packToReceipt(this.fields, this.form, ruleTaskSettlement);
        params = this.packFormat(params);

        params = this.globalFormSubmissionDataProcessingHandler(
          this.fields,
          params
        );
        
        // 结算规则
        params.taskSettlement = ruleTaskSettlement;
        params.settlementCurrency = this.currencyType;
        params.baseTaskFaultLibrary = this.form?.newFaultLibrary || [];
        params.sparePartsReturnExpense = this.form?.sparePartsReturnExpense || [];

        this.pending = true;

        // 开启支付时判断支付状态
        if (this.openPay) {
          const data = await TaskApi.getPaymentOrder({
            taskId: this.task.id,
          });
          if (data.success) {
            let statusArr = ['init', 'process', 'success'];
            let { status } = data.result;

            if (
              statusArr.indexOf(status) > -1 &&
              statusArr.indexOf(status) < 2
            ) {
              this.pending = false;
              this.$platform.alert(
                i18n.t('task.tip.receiptTip9')
              );
              return;
            }
          }
        }

        if (this.action === 'edit') return this.editReceipt(params);
        this.finish(params);
      } catch(error) {
        console.error('completionReceipt =>', error)
      }
    },
    /**
     * @description 完成
     */
    async finish(params) {

      // 结算规则
      let ruleTaskSettlement = this.taskSettlementFunc();


      let approvalParams = {
        ...util.packToReceipt(this.fields, this.form, ruleTaskSettlement, this.isShowSettlementRules ? this.finalTotalAmount : this.totalData?.[0]?.totalExpense),
        createProByMat: this.form.createProByMat,
        banProductIds: this.form.banProductIds,
        taskSettlement: ruleTaskSettlement,
        finalTotalAmount: this.isShowSettlementRules ? this.finalTotalAmount : this.totalData[0]?.totalExpense,
        settlementCurrency: this.currencyType
      }
      approvalParams.baseTaskFaultLibrary = approvalParams.task?.attribute?.newFaultLibrary;
      approvalParams.sparePartsReturnExpense = approvalParams.task?.attribute?.sparePartsReturnExpense || [];

      approvalParams.task = disposeFormSubmitTime(this.fields, approvalParams.task)

      // 先判断是否需要高级审批
      let approveParams = {
        taskId: this.task.id,
        action: 'finish',
        receiptInfo: {
          ...approvalParams
        }
      }

      const approveResult = await TaskApi.checkNeedVipApprove(approveParams);
      if (approveResult.success && approveResult.result.needVipApprove) {
        this.$emit('proposeApprove', approveResult.result);
        this.pending = false;
        return
      }


      // 回访是否需要审批
      const result = await TaskApi.finishApproveCheck(approvalParams);
      // fix 15762

      if(!result.succ && result.errorCode == 10001) {
        this.$platform.confirm(result.message)
        this.pending = false;
        return
      }

      if(!result.succ && result.errorCode == 10002) {
        this.$platform.confirm(i18n.t('task.tip.startTaskTip1'))
        this.pending = false;
        return
      }

      // TODO 需要审批判断改成errorCode
      if (!result.succ && Number(result.errorCode) == 10003) {
        this.visible = false;
        this.pending = false;

        this.$emit('proposeApprove', result.data);
        return;
      }

      if (!(await this.$platform.confirm(i18n.t('task.tip.confirmOperationTip', {name: i18n.t('common.base.finish')}))))
        return (this.pending = false);

      if(this.needServerDeleFiles.length){
        params.deleteFiles = this.needServerDeleFiles
      }

      TaskApi.finishTask(params)
        .then(res => {
          if (res.success) {
            this.$platform.notification({
              type: 'success',
              title: i18n.t('common.base.submitSuccess'),
            });

            this.refreshTab();
          } else {
            this.$platform.alert(res.message);
            this.pending = false;

            // 回执备件来源和当前租户备件库配置不同
            if (res.code == 159753) {
              this.$eventBus.$emit('task_receipt_update_sparepart_config');

              // 获取备件清单数据
              if (this.showSparepart) this.getInventoryRecordGroup();
            }
          }
        })
        .catch(err => {
          this.pending = false;
        });
    },
    /**
     * @description 编辑回执
     */
    async editReceipt(params) {
      if (!(await this.$platform.confirm(i18n.t('task.tip.confirmOperationTip', {name: i18n.t('common.base.edit')}))))
        return (this.pending = false);    

      if(this.needServerDeleFiles.length){
        params.deleteFiles = this.needServerDeleFiles
      }

      TaskApi.editReceipt(params)
        .then(res => {
          if (res.success) {
            this.$platform.notification({
              type: 'success',
              title: i18n.t('common.base.tip.edit2Success'),
            });

            this.refreshTab();
          } else {
            this.$platform.alert(res.message);
            this.pending = false;

            // 回执备件来源和当前租户备件库配置不同
            if (res.code == 159753) {
              this.$eventBus.$emit('task_receipt_update_sparepart_config');

              // 获取备件清单数据
              if (this.showSparepart) this.getInventoryRecordGroup();
            }
          }
        })
        .catch(err => {
          this.pending = false;
        });
    },
    updateServiceList({ data, fields }) {
      this.serviceList = data || [];
      this.serviceFields = fields || [];
    },
    /**
     * @description 获取备件清单
     */
    getInventoryRecordGroup() {
      let { cardId } = this.sparepartCard || {};
      if (!cardId) return;

      this.sparepartList = [];
      TaskApi.getInventoryRecordGroup({ taskId: this.task.id, cardId })
        .then(res => {
          if (res.success) {
            this.sparepartList = (res.result || []).filter(x => x.sparePartUseNum > 0);
            this.sparepartList.forEach(item => {
              item.oldPrice = item.salePrice;
              item.sparePartId = item.id;
              item.sort = item.type;
            });

            // 获取备件清单中备件可申请的仓库
            let ids = this.sparepartList.map(item => {
              return item.sparePartId;
            });
            this.getRepertoryBySparePartIds([...new Set(ids)]);

            this.$nextTick(() => {
              this.updateConfigForSparepart();
            });
          }
        })
        .catch(err => console.error(err));
    },
    /**
     * @description 获取备件清单中备件可申请的仓库
     */
    getRepertoryBySparePartIds(ids) {
      TaskApi.getRepertoryBySparePartIds(ids)
        .then(res => {
          if (res.success) {
            res.result.map(part => {
              let spareparts = this.sparepartList.filter(
                item => item.sparePartId == part.id
              );

              spareparts.forEach(sparepart => {
                // 可申请仓库列表
                let repertorys = part.baseRepertorySpareparts || [];
                repertorys.forEach(item => {
                  item.repertoryName = item?.baseRepertory?.name || '';
                });

                sparepart.repertorys = repertorys;
                sparepart.personalRepertory = part.baseUserSparepart;
              });
            });
          }
        })
        .catch(err => console.error(err));
    },
    updateConfigForSparepart() {
      let config = {
        editUnitPrice: this.taskType?.options?.editUnitPrice || false,
        isPaySuccess: this.isPaySuccess,
        serviceList: this.serviceList,
        serviceFields: this.serviceFields,
        sparepartCard: this.sparepartCard,
        sparepartList: this.sparepartList,
        sparePartCardList: this.sparePartCardList
      };

      this.$eventBus.$emit('task_receipt_update_config', config);
    },
    /**
     * @description 获取物料返还方式信息
     */
    async updateMaterialReturnInformation({ form }) {
      this.form.materialReturnInformation = form;

      // 审批中暂存
      if(this.task?.inApprove == 1){
        if (!(await this.$platform.confirm(i18n.t('task.tip.confirmOperationTip', {name: i18n.t('common.base.edit')}))))
        return (this.pending = false);

        return this.draft();
      }

      if (this.isMaterialVerifyEliminate) {
        return this.verificationMaterialOutWarehouseComplete();
      }
      return this.completionReceipt()
    },
    // 刷新本页面&进入的列表tab
    refreshTab() {
      // let fromId = window.frameElement.getAttribute('fromid')
      // this.$platform.refreshTab(fromId)

      window.location.href = `${this.$resourcePrefix}/task/view/${this.task.id}`;
    },
    handleCancel() {
      this.$track.clickStat(this.$track.formatParams('CANCEL', '取消', 'FINISH_TASK'));
      this.visible = false;
      this.needServerDeleFiles = []
    },
    getInCheck(val) {
      if (!val) return false
      return this.form?.materialVerifyEliminate?.length && this.form.materialVerifyEliminate.some(item => (item.warrantyStatus === i18n.t('common.base.warranty') || item.warrantyStatus === '保内'))
    },

    getOutCheck(val) {
      if (!val) return false
      return this.form?.materialVerifyEliminate?.length && this.form.materialVerifyEliminate.some(item => (item.warrantyStatus === i18n.t('common.base.surrender') || item.warrantyStatus === '保外'))
    },

    getAllCheck(val) {
      if (!val) return false
      return this.form?.materialVerifyEliminate?.length > 0
    },
    getAllSparepartCheck(val) {
      if (!val) return false
      return this.form?.sparepart?.length > 0
    },
    getInSparepartCheck(val) {
      if (!val) return false
      return this.sparePartCardList?.length > 0
    },
    async getCurrencyType(target) {
      let { materialVerifyEliminate=[], serviceIterm=[] } = this.form
      if(materialVerifyEliminate.length > 0 || serviceIterm.length > 0) {
        this.fieldArr = materialVerifyEliminate.concat(serviceIterm)
        let currencyTypeArr = []
        let manualArr = []
        this.fieldArr.forEach(item => {
          let salePriceCurrency = item.salePriceCurrency ? item.salePriceCurrency : 'CNY'
          if(!(currencyTypeArr.includes(salePriceCurrency))) {
            currencyTypeArr.push(salePriceCurrency)
          }
          if(salePriceCurrency != target) {
            manualArr.push(item)
          }
        })
        let index = (manualArr || []).findIndex(item=> item.exchangeMethod == 2)
        if(index>-1) this.$platform.alert(i18n.t('common.currency.manulExchangeRateTip'))
        let exchangeRateObj = {}
        if(currencyTypeArr.length > 0) {
          let { status, data } = await TaskApi.queryRateList({sourceList: currencyTypeArr, target})
          if(status !== 0)  return this.$platform.alert(i18n.t('common.currency.queryException'));
          exchangeRateObj = data.result
        }
        localStorage.setItem(`set_curreny_key_${this.task.id}`, JSON.stringify(exchangeRateObj))
        this.$eventBus.$emit('task_receipt_update_currency-type', exchangeRateObj);
      }
    },
    updateCurrencyType(data) {
      localStorage.removeItem(`set_curreny_key_${this.task.id}`)
      this.getCurrencyType(data.newValue)
    },
    /**
     * @des 已申领未核销的物料必须返还校验
     */
    async validateReturnUnusedCheck(){
      try {
        let getValiteReturnUnusedCheckRes = await TaskApi.getValiteReturnUnusedCheck({
          taskId:this.task.id
        })
        const { result, code } = getValiteReturnUnusedCheckRes
        if(code !== 0) throw(getValiteReturnUnusedCheckRes)
        let { materialReturn, materialVerifyEliminate } = this.form;
        let validateMap = {}
        let realNum = {}
        result.forEach(item=>{
          const { materialId, num, materialName } = item;
          validateMap[materialId] = {num, name:materialName}
        })
        // 遍历物料返还 累加获得实际返还的数量
        materialReturn.length && materialReturn.forEach(item=>{
          let key_ = item.primaryId || item.materialId || item.id
          if(Reflect.has(validateMap, key_)){
            realNum[key_] = (realNum[key_]? realNum[key_] * 1 : 0) + item.number
          }
        })
        // 遍历物料核销 减去核销的物料获得需要返还的数量
        materialVerifyEliminate.length && materialVerifyEliminate.forEach((item)=>{
          let key_ = item.primaryId || item.materialId || item.id
          if(Reflect.has(validateMap, key_)){
            validateMap[key_].num = (validateMap[key_].num? validateMap[key_].num * 1 : 0) - item.number
          }
        })
        let boolean = true
        for(let key in validateMap){
          const item = validateMap[key]
          const { num, name } = item
          if(!Reflect.has(realNum, key)){
            if(num > 0){
              boolean = false
              console.warn('erro result -> validateMap', validateMap)
              console.warn('erro result -> realNum', realNum)
              this.$platform.notification({
                type: 'error',
                title: this.$t('common.base.toast'),
                message:this.$t('common.task.materialReturn.tips', {name, num, num2:0})
              });
              break
            }
          }else{
            // 可以还多不能换少
            if((realNum[key] || 0 ) < num){
              boolean = false
              console.warn('erro result -> validateMap', validateMap)
              console.warn('erro result -> realNum', realNum)
              this.$platform.notification({
                type: 'error',
                title: this.$t('common.base.toast'),
                message:this.$t('common.task.materialReturn.tips', {name, num, num2:realNum[key]})
              });
              break
            }
          }
        }
        return Promise.resolve(boolean)
      } catch (error) {
        console.warn(error, 'error try catch validateReturnUnusedCheck');
        return Promise.resolve(true)
      }
    },
    async initFormBuilderCellCount(){
      const { getSystemFormBuilderCell } = useStateSystemFormBuilderCell()
      let count = await getSystemFormBuilderCell()
      this.formCellCount = count || 1;
    },
    watchRootChange() {
      window.addEventListener('message', event => {
        const { action, number } = event.data;
        if (action == 'changeAllFormBuilderCell') {
          this.formCellCount = number;
        }
      });
    },
    getDeleteFiles(files){
      this.needServerDeleFiles = [...this.needServerDeleFiles,...files]
    }
  },
  async mounted() {

    this.$eventBus.$on('task_service_list_update', this.updateServiceList);

    // 在线支付成功
    // TODO：payment服务已废弃，拿不到数据，暂时注释
    // if (this.isPaySuccess) await this.getPaymentMethodDetail();

    await this.fetchRuleList()
    await this.initFormBuilderCellCount()
    this.watchRootChange()
  },
  beforeDestroy() {
    this.$eventBus.$off('task_service_list_update', this.updateServiceList);
  },
  watch: {
    totalExpense(newValue) {
      // 折扣费用大于总价
      if (newValue < 0) this.form.disExpense = 0;
    },

    // 物料核销必填校验
    'form.materialVerifyEliminate'(newValue) {
      // 物料返还
      const field = this.fields.filter(item => item.formType === 'materialReturn')
        if (field?.[0]) { {
          field[0].isNull = 1 // 默认不是必填的
          let flag = false
          if (newValue?.length > 0) {
        // expiredMaterialReturnCheck 质保期为保内的物料必须返还
        // unexpiredMaterialReturnCheck 质保期为保外的物料必须返还
        // writtenOffMaterialReturnCheck 已核销的物料必须返还 （只要添加了物料核销就必填）
          const { expiredMaterialReturnCheck, unexpiredMaterialReturnCheck, writtenOffMaterialReturnCheck} = field?.[0]?.setting || {}
            flag = this.getInCheck(expiredMaterialReturnCheck) || this.getOutCheck(unexpiredMaterialReturnCheck) || this.getAllCheck(writtenOffMaterialReturnCheck)
            if (flag) {
              field[0].isNull = 0
            }
          }
        }
      }
    },
    // 备件返还必填校验
    'form.sparepart'(newValue) {
      if(!this.isSparePartsReturnExpense) return;
      // 备件返还
      const field = this.fields.filter(item => item.formType === 'sparePartsReturnExpense');
      if (field?.[0]) {
        field[0].isNull = 1; // 默认不是必填的
        let flag = false;

        // usedSparePartMustReturn 已核销备件的旧件必须返还（只要添加了备件就必填）
        // applySparePartMustReturn 已申领未核销的备件必须返还
        const { usedSparePartMustReturn, applySparePartMustReturn } = field?.[0]?.setting || {};
        flag = this.getAllSparepartCheck(usedSparePartMustReturn) || this.getInSparepartCheck(applySparePartMustReturn);
        
        if (flag) {
          field[0].isNull = 0
        }
      }
    },
  },
  components: {
    [MaterialReturnInformationDialog.name]: MaterialReturnInformationDialog,
    [MaterialReconfirmDialog.name]: MaterialReconfirmDialog,
    [FaultTable.name]: FaultTable,
    [FormCellChange.name]: FormCellChange
  },
};
